<?php
// +----------------------------
// | Created by PhpStorm
// +----------------------------
// | Author: YnnSon
// +----------------------------
namespace app\api\service;

use app\lib\enum\VehicleEnum;
use app\lib\exception\VehicleException;
use think\Config;
use Yurun\Util\HttpRequest;

class Vehicle
{
    private $config;

    public function __construct()
    {
        $this->config = Config::get('vehicle');
    }

    /**
     * @Desc 违章查询
     *
     * @param $param
     *
     * @return mixed
     */
    public function violation($param)
    {
        return $this->fakeData()['showapi_res_body'];
        $url = $this->config['violation_url'];
        return $this->requestData($url, $param);
    }

    /**
     * @Desc 支持列表与规则查询
     *
     * @param $param
     *
     * @return mixed
     */
    public function violationRule($param)
    {
        if ('黑A' == $param['preCarNum']) {
            return $this->ruleError()['showapi_res_body'];
        }
        if ('辽A' == $param['preCarNum']) {
            return $this->ruleSuccess()['showapi_res_body'];
        }
        throw new VehicleException();
        $url = $this->config['violation_rule_url'];
        return $this->requestData($url, $param);
    }

    /**
     * @Desc 请求违章查询接口
     *
     * @param $url
     * @param $param
     *
     * @return mixed
     */
    private function requestData($url, $param)
    {
        $param['showapi_appid'] = $this->config['showapi_appid'];
        $param['showapi_timestamp'] = date('YmdHis');
        ksort($param);
        $param['showapi_sign'] = $this->sign($param);
        array_walk($param, static function (&$value) {
            $value = trim($value);
        });
        $query = http_build_query($param);
        $requestBody = urldecode($query);
        // carCode=037572&carEngineCode=366893&carNumber=贵AH171R&carType=02&showapi_appid=185335&showapi_timestamp=20200727102224&showapi_sign=3600bcf9a716eb9bd8b9825e589ab364
        // $fakeData = $this->fakeData2();
        // return $fakeData['showapi_res_body'];
        $http = new HttpRequest();
        $header = [
            'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
        ];
        $response = $http->headers($header)->post($url, $requestBody)->body();
        $result = json_decode($response, true);
        if (0 !== $result['showapi_res_code']) {
            throw new VehicleException();
        }
        return $result['showapi_res_body'];
    }

    /**
     * @Desc 驾照查分
     *
     * @param $param
     *
     * @return mixed
     */
    public function score($param)
    {
        $url = $this->config['score_url'];
        $param['appkey'] = $this->config['score_appkey'];
        return [
            'licensenumber' => '230822197707070077',
            'licenseid'     => '123456798012',
            'score'         => '4',
        ];
        $http = new HttpRequest();
        $response = $http->post($url, $param)->json(true);
        $status = substr($response['status'], 0, 1);
        if (VehicleEnum::ERROR_SYSTEM == $status) {
            throw new VehicleException();
        }
        if (VehicleEnum::ERROR_API == $status) {
            throw new VehicleException([
                'message' => $response['msg'],
            ]);
        }
        return $response['result'];
    }

    private function fakeData()
    {
        $data = '{
            "showapi_res_error": "",
            "showapi_res_code": 0,
            "showapi_res_id": "5f2bc4ca8d57ba666e40d23d",
            "showapi_res_body": {
                "count": 1,
                "carEngineCode": "017634",
                "showapi_fee_code": 0,
                "carCode": "000070",
                "errorMsg": "查询成功!",
                "msg": "查询成功!",
                "carType": "02",
                "ret_code": 0,
                "flag": true,
                "carNumber": "辽AP688F",
                "errorCode": 0,
                "createDate": 1596703946245,
                "records": [
                    {
                        "time": "2020-07-28 14:49:15",
                        "degree": "6",
                        "reason": "驾驶机动车通过交叉路口时，违反道路交通信号灯通行的",
                        "address": "解放大街全路段",
                        "department": "",
                        "cityName": "黑龙江哈尔滨",
                        "money": "200",
                        "code": "1625"
                    }
                ],
                "createDateStr": "2020-08-06 16:52:26"
            }
        }';
        return json_decode($data, true);
    }

    private function ruleSuccess()
    {
        $data = '{
            "showapi_res_error": "",
            "showapi_res_code": 0,
            "showapi_res_id": "5f2bc3968d57ba676e435fa8",
            "showapi_res_body": {
                    "ret_code": "0",
                "flag": true,
                "preCarNum": "辽A",
                "remark": "查询成功!",
                "data": [
                    {
                        "scope": 0,
                        "carCodeLen": 6,
                        "carTypeScope": "0",
                        "preCarNum": "辽A",
                        "cityName": "沈阳",
                        "province": "辽宁",
                        "carEngineLen": 6,
                        "jgjId": ""
                    }
                ],
                "showapi_fee_code": 0,
                "msg": "查询成功!"
            }
        }';
        return json_decode($data, true);
    }

    private function ruleError()
    {
        $data = '{
            "showapi_res_error": "",
            "showapi_res_code": 0,
            "showapi_res_id": "5f2bc27c8d57ba666e7feb37",
            "showapi_res_body": {
                "ret_code": "-1",
                "flag": false,
                "preCarNum": "黑A",
                "showapi_fee_code": -1,
                "msg": "没有找到相关数据!"
            }
        }';
        return json_decode($data, true);
    }

    /**
     * @Desc md5签名
     *
     * @param $param
     *
     * @return string
     */
    private function sign($param)
    {
        $str = '';
        foreach ($param as $key => $value) {
            null != trim($value) && $str .= $key . trim($value);
        }
        $str .= $this->config['showapi_secret'];
        return md5($str);
    }
}